#pragma once

#include <AST/ExprAST.hpp>
#include <llvm/ADT/SmallVector.h>

class Expr;

class PrototypeAST : public Expr {
  protected:
    using ParaTypeVector = llvm::SmallVector<Type *>;
    using ParaNameVector = llvm::SmallVector<string>;
    using ParaIsRefVector = llvm::SmallVector<bool>;

  private:
    // 函数名
    string funName;

    // 形参类型列表
    ParaTypeVector paraTypes;

    // 形参名字列表
    ParaNameVector paraNames;

    // 每个参数是否引用
    ParaIsRefVector paraIsRefs;

    // 返回值类型
    Type *returnType;

  public:
    PrototypeAST(
        string funName,
        ParaTypeVector paraTypes,
        ParaNameVector paraNames,
        ParaIsRefVector paraIsRefs,
        Type *returnType);

    FunctionType *getFunctionType() const;

    virtual llvm::Function *codegen() override;

    const string &getFunName() const { return funName; }

    Type *getParaType(unsigned int i) const;

    bool getParaIsRef(unsigned int i) const;

    friend class graphviz::GraphGenerator;

    virtual VisitResult accept(ASTVisitor &visitor) const override {
        return visitor.visitPrototypeAST(this);
    }
};